package dev.ece.suit.hexmap;

import java.util.ArrayList;
import java.util.List;

import dev.ece.core.vertex.VAO;
import dev.ece.core.vertex.VBO;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;

public class MapCellVAO {
	
	private VBO verticeVBO;
	
	private VBO uvVBO;
	
	private VBO blendUVVBO;
	
	private VBO normalsVBO;
	
	private VAO vao;
	
	protected MapCellVAO(VBO verticeVBO, VBO uvVBO, VBO normalsVBO, VBO blendUVVBO) {
		this.verticeVBO = verticeVBO;
		this.uvVBO = uvVBO;
		this.normalsVBO = normalsVBO;
		this.blendUVVBO = blendUVVBO;
	}
	
	public static MapCellVAO createMapCellVAO(TerrainModelCreator terrainModelCreator, MapCell[][] cells) {
		List<Vector3f> vertice = new ArrayList<Vector3f>();
		List<Vector2f> uv = new ArrayList<Vector2f>();
		List<Vector2f> blenduv = new ArrayList<Vector2f>();
		List<Vector3f> normals = new ArrayList<Vector3f>();
		MapCell[] cols = null;
		for(int row=0; row<cells.length; row++) {
			cols = cells[row];
			for(int col=0; col<cols.length; col++) {
				terrainModelCreator.getMapCellCreator().fillData(cols[col], vertice, uv, normals, blenduv);
			}
		}
		VBO verticeVBO = VBO.newInstance3f(vertice);
		VBO uvVBO = VBO.newInstance2f(uv);
		VBO normalsVBO = VBO.newInstance3f(normals);
		VBO blendUVVBO = VBO.newInstance2f(blenduv);
		
		vertice.clear();
		uv.clear();
		blenduv.clear();
		normals.clear();
		
		vertice = null;
		uv = null;
		blenduv = null;
		normals = null;
		return new MapCellVAO(verticeVBO, uvVBO, normalsVBO, blendUVVBO);
	}
	
	public void initialize() {
		vao = new VAO();
		vao.bind();
		vao.bindVertexArrayBuffer(verticeVBO, 3);
		vao.bindVertexArrayBuffer(uvVBO, 2);
		vao.bindVertexArrayBuffer(normalsVBO, 3);
		vao.bindVertexArrayBuffer(blendUVVBO, 2);
		vao.finish();
		
		verticeVBO = null;
		uvVBO = null;
		blendUVVBO = null;
		normalsVBO = null;
	}
	
	public void destroy() {
		if(vao != null) {
			vao.destroy();
			vao = null;
		}
	}
	
	public void bind() {
		vao.bind();
	}
	
}
